from getdata import read_excel_file
from hashdata import hash_dataframe
import pandas as pd
import qrcode
import json
from io import BytesIO
import base64
import uuid
from datetime import datetime
import os
from display import display_images_with_opencv

class DataFrameQREncoder:
    """
    将DataFrame数据分块编码为二维码的类
    """
    
    def __init__(self, task_id=None, chunk_size=None):
        # 加载配置文件
        config_path = os.path.join(os.path.dirname(__file__), "config.json")
        try:
            with open(config_path, 'r', encoding='utf-8') as f:
                config = json.load(f)
            encodedata_config = config.get("encodedata", {})
            
            # 如果参数为None，则从配置文件中读取
            if chunk_size is None:
                chunk_size = encodedata_config.get("chunk_size", 10)
                
            # 保存配置到实例变量
            self.encodedata_config = encodedata_config
        except Exception as e:
            print(f"无法加载配置文件，使用默认值: {e}")
            # 使用默认值
            if chunk_size is None:
                chunk_size = 10
            self.encodedata_config = {"chunk_size": 10}
        """
        初始化
        
        参数:
            task_id (str): 任务ID，如果为None则自动生成
            chunk_size (int): 每个分块的行数
        """
        self.chunk_size = chunk_size
        self.qr_codes = []
        self.hash_value = None

    
    def _dataframe_to_csv_chunks(self, df):
        """
        将DataFrame切分为CSV格式的分块
        
        返回:
            list: 包含每个分块CSV字符串的列表
        """
        if df is None or df.empty:
            raise ValueError("DataFrame为空或None")

        # 计算哈希值
        self.hash_value = hash_dataframe(df)
        
        # 获取总行数
        total_rows = len(df)
        
        # 计算总组数
        total_chunks = (total_rows + self.chunk_size - 1) // self.chunk_size
        
        chunks = []
        
        for i in range(total_chunks):
            # 计算当前分块的起始和结束索引
            start_idx = i * self.chunk_size
            end_idx = min((i + 1) * self.chunk_size, total_rows)
            
            # 获取当前分块的数据
            chunk_df = df.iloc[start_idx:end_idx]

            # 计算当前分块的哈希值
            chunk_hash = hash_dataframe(chunk_df)
            
            # 转换为CSV字符串（包含表头）
            csv_data = chunk_df.to_csv(index=False)
            
            # 构建包含冗余信息的数据结构
            chunk_info = {
                "task_hash": self.hash_value,
                "chunk_hash": chunk_hash,
                "total_chunks": total_chunks,
                "current_chunk": i + 1,  # 从1开始计数
                "total_rows": total_rows,
                "data": csv_data
            }
            
            chunks.append(chunk_info)
        
        return chunks
    
    def _create_qr_code(self, data, size=None, border=None):
        # 从配置中获取参数，如果传入了参数则优先使用传入的参数
        if size is None:
            size = self.encodedata_config.get("qr_size", 10)
        if border is None:
            border = self.encodedata_config.get("qr_border", 2)
        """
        创建二维码
        
        参数:
            data: 要编码的数据
            size (int): 二维码尺寸
            border (int): 边框大小
        
        返回:
            tuple: (二维码图像, 编码数据)
        """
        # 将数据转换为JSON字符串
        if isinstance(data, dict):
            json_data = json.dumps(data, ensure_ascii=False)
        else:
            json_data = str(data)
        
        # 创建二维码
        qr = qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_H,
            box_size=size,
            border=border,
        )
        qr.add_data(json_data)
        qr.make(fit=True)
        
        # 生成二维码图像
        img = qr.make_image(fill_color="black", back_color="white")
        
        return img, json_data
    
    def encode_dataframe_to_qr(self, df, output_dir=None, save_images=None):
        # 从配置中获取参数，如果传入了参数则优先使用传入的参数
        if output_dir is None:
            output_dir = self.encodedata_config.get("output_dir", "qr_output")
        if save_images is None:
            save_images = self.encodedata_config.get("save_images", True)
        """
        将DataFrame编码为多个二维码
        
        参数:
            df (DataFrame): 要编码的DataFrame
            output_dir (str): 保存二维码图像的目录
            save_images (bool): 是否保存二维码图像文件
        
        返回:
            list: 包含每个分块信息的列表
        """
        # 创建输出目录
        if save_images and not os.path.exists(output_dir):
            os.makedirs(output_dir)

        # 将DataFrame切分为分块
        chunks = self._dataframe_to_csv_chunks(df)
        
        results = []
        
        for i, chunk_info in enumerate(chunks):
            # 创建二维码
            qr_img, encoded_data = self._create_qr_code(chunk_info)
            
            # 保存二维码图像
            if save_images:
                filename = f"{self.hash_value}_chunk_{i+1:03d}.png"
                filepath = os.path.join(output_dir, filename)
                qr_img.save(filepath)
        
        display_images_with_opencv(output_dir, max_height=800, display_time=2)
        


if __name__ == "__main__":
    data = read_excel_file("../iES_DB-20251009.xlsx")
    
    # 创建编码器实例（现在会从配置文件读取参数）
    encoder = DataFrameQREncoder()
    
    # 将数据编码为二维码（现在会从配置文件读取参数）
    encoder.encode_dataframe_to_qr(data)